# load pretty jupyter's magics
%load_ext pretty_jupyter
The pretty_jupyter extension is already loaded. To reload it, use: %reload_ext pretty_jupyter
Types of Image Segmentation¶
Set environment¶
# Get common packages
import os
import shutil
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from skimage import data
# Set image path
img_name = 'bee'
img_path = '../data/images/border-collie-8287329_640.webp'
original_image = np.array(Image.open(img_path))
# original_image = data.coffee()
# original_image = data.astronaut()
# define common function
def plot_image_comparision(img_1, img_2, draw_colorbar:bool=False):
plt.figure(figsize=(15, 15))
plt.subplot(1, 2, 1)
plt.imshow(img_1)
plt.subplot(1, 2, 2)
plt.imshow(img_2, cmap="gray")
if draw_colorbar:
colorbar = plt.imshow(img_2)
plt.colorbar(colorbar, fraction=0.046, pad=0.04)
Color spaces manipulation¶
# Importing Necessary Libraries
from skimage.color import rgb2gray, rgb2hsv
gray_img = rgb2gray(original_image)
hsv_img = rgb2hsv(original_image)
plot_image_comparision(original_image, gray_img, draw_colorbar=False)
plot_image_comparision(original_image, hsv_img, draw_colorbar=True)
Segmentação por limiarização (Thresholding)¶
Divide uma imagem em regiões com base em um valor de limiar, onde os pixels acima do limiar são atribuÃdos a uma região e os pixels abaixo do limiar a outra.
- É útil para segmentar objetos do fundo em imagens binárias.
# Importing Necessary Libraries
from skimage import filters
from skimage.color import rgb2gray
gray_img = rgb2gray(original_image)
# Setting the plot size to 15,15
plt.figure(figsize=(15, 15))
for i in range(10):
# Iterating different thresholds
binarized_gray = (gray_img > i*0.1)*1
plt.subplot(5,2,i+1)
# Rounding of the threshold
# value to 1 decimal point
plt.title(f"Threshold: >{str(round(i*0.1,1))} ({str(i*0.1*256)})")
# Displaying the binarized image
# of various thresholds
plt.imshow(binarized_gray, cmap = 'gray')
plt.tight_layout()
# Importing necessary libraries
from skimage import filters
from skimage.color import rgb2gray
import matplotlib.pyplot as plt
# Setting plot size to 15, 15
plt.figure(figsize=(15, 15))
gray_img = rgb2gray(original_image)
# Computing Otsu's thresholding value
threshold = filters.threshold_otsu(gray_img)
# Computing binarized values using the obtained
# threshold
binarized_coffee = (gray_img > threshold)*1
plt.subplot(2,2,1)
plt.title("Threshold: >"+str(threshold))
# Displaying the binarized image
plt.imshow(binarized_coffee, cmap = "gray")
# Computing Ni black's local pixel
# threshold values for every pixel
threshold = filters.threshold_niblack(gray_img)
# Computing binarized values using the obtained
# threshold
binarized_coffee = (gray_img > threshold)*1
plt.subplot(2,2,2)
plt.title("Niblack Thresholding")
# Displaying the binarized image
plt.imshow(binarized_coffee, cmap = "gray")
# Computing Sauvola's local pixel threshold
# values for every pixel - Not Binarized
threshold = filters.threshold_sauvola(gray_img)
plt.subplot(2,2,3)
plt.title("Sauvola Thresholding")
# Displaying the local threshold values
plt.imshow(threshold, cmap = "gray")
# Computing Sauvola's local pixel
# threshold values for every pixel - Binarized
binarized_coffee = (gray_img > threshold)*1
plt.subplot(2,2,4)
plt.title("Sauvola Thresholding - Converting to 0's and 1's")
# Displaying the binarized image
plt.imshow(binarized_coffee, cmap = "gray")
<matplotlib.image.AxesImage at 0x234c0c7a020>
Segmentação por contorno ativo (Active Contour)¶
- Envolve a definição de uma curva fechada (contorno) que se ajusta ao redor dos objetos na imagem.
- Abordagem de segmentação que utiliza forças e restrições de energia para separar os pixels de interesse do resto da imagem
# Importing necessary libraries
import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage.filters import gaussian
from skimage.segmentation import active_contour
# Sample Image of scikit-image package
gray_img = rgb2gray(original_image)
# Applying Gaussian Filter to remove noise
gray_img_noiseless = gaussian(gray_img, 1)
# Localising the circle's center at 220, 110
x1 = 220 + 100*np.cos(np.linspace(0, 2*np.pi, 500))
x2 = 100 + 100*np.sin(np.linspace(0, 2*np.pi, 500))
# Generating a circle based on x1, x2
snake = np.array([x1, x2]).T
# Computing the Active Contour for the given image
astronaut_snake = active_contour(gray_img_noiseless,
snake)
fig = plt.figure(figsize=(10, 10))
# Adding subplots to display the markers
ax = fig.add_subplot(111)
# Plotting sample image
ax.imshow(gray_img_noiseless)
# Plotting the face boundary marker
ax.plot(astronaut_snake[:, 0],
astronaut_snake[:, 1],
'-b', lw=5)
# Plotting the circle around face
ax.plot(snake[:, 0], snake[:, 1], '--r', lw=5)
[<matplotlib.lines.Line2D at 0x234c0fc1b10>]
Chan-Vese Segmentation¶
O método de segmentação iterativo Chan-Vese divide uma imagem em dois grupos com a menor variância intra-classe.
Syntax : skimage.segmentation.chan_vese(image)
Parameters :
- image : An image
- mu : Weight – Edge Length
- lambda1 : Weight – Difference from average
- tol : Tolerance of Level set variation
- max_num_iter : Maximum number of iterations
- extended_output : Tuple of 3 values is returned
Return :
- segmentation : Segmented Image
- phi : Final level set
- energies: Shows the evolution of the energy
import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage.segmentation import chan_vese
fig, axes = plt.subplots(1, 3, figsize=(10, 10))
gray_img = rgb2gray(original_image)
# Computing the Chan VESE segmentation technique
chanvese_gray_img = chan_vese(gray_img,
max_num_iter=100,
extended_output=True)
ax = axes.flatten()
# Plotting the original image
ax[0].imshow(gray_img, cmap="gray")
ax[0].set_title("Original Image")
# Plotting the segmented - 100 iterations image
ax[1].imshow(chanvese_gray_img[0], cmap="gray")
title = "Chan-Vese segmentation - 100 iterations"
format(len(chanvese_gray_img[2]))
ax[1].set_title(title)
# Plotting the final level set
ax[2].imshow(chanvese_gray_img[1], cmap="gray")
ax[2].set_title("Final Level Set")
plt.show()
Segmentação não supervisionada¶
- Agrupa pixels semelhantes em regiões maiores com base em critérios como cor, textura e proximidade espacial.
# Importing required boundaries
from skimage.segmentation import slic, mark_boundaries
# Applying SLIC segmentation
# for the edges to be drawn over
img_segments = slic(original_image,
n_segments=100,
compactness=1)
plot_image_comparision(original_image,
mark_boundaries(original_image, img_segments))
plot_image_comparision(original_image, img_segments)
Simple Linear Iterative Clustering¶
# Importing required libraries
from skimage.segmentation import slic
from skimage.color import label2rgb
# Applying Simple Linear Iterative
# Clustering on the image
# - 50 segments & compactness = 10
img_segments = slic(original_image,
n_segments=50,
compactness=10)
segmented_img = label2rgb(img_segments,
original_image,
kind = 'avg')
plot_image_comparision(original_image, segmented_img)
Felzenszwalb’s Segmentation¶
# Importing the required libraries
from skimage.segmentation import felzenszwalb, mark_boundaries
# Setting the figure size as 15, 15
plt.figure(figsize=(15,15))
# computing the Felzenszwalb's
# Segmentation with sigma = 5 and minimum
# size = 100
img_segments = felzenszwalb(original_image,
scale = 2,
sigma=5,
min_size=100)
plot_image_comparision(original_image,
mark_boundaries(original_image, img_segments))
plot_image_comparision(original_image, img_segments)
<Figure size 1500x1500 with 0 Axes>
Export notebook¶
!Powershell.exe -Command "jupyter nbconvert --to html --template pj types_of_segmentations.ipynb"
shutil.move('types_of_segmentations.html', f'../output/notebooks/{img_name}.html')
'../output/notebooks/bedroom.html'